import java.util.ArrayList;

// 单例模式:创建的同一类对象地址值是一样的
public class SingletonPattern {
    public static void main(String[] args) {
//        HungrySingleton instance = HungrySingleton.getInstance();
//        HungrySingleton instance2 = HungrySingleton.getInstance();
//        System.out.println(instance);
//        System.out.println(instance2);
        Car car = Car.getCar();
        Car car1 = Car.getCar();
        Car car2 = Car.getCar();
        Car car3 = Car.getCar();

        System.out.println(car);
        System.out.println(car1);
        System.out.println(car2);
        System.out.println(car3);
//
//        for (int i = 0; i < 100; i++) {
//            new MyThread().start();
//        }

        Tom tom = new Tom();

    }
}

class  MyThread extends Thread{
    public void run(){
        Car car = Car.getCar();
        System.out.println(car);
    }
}

class  Car {

    public volatile static Car car;

    public static Car getCar(){
        if(null == car){
            synchronized (Car.class) {
                if(null == car){
                    car = new Car();
                }
            }
        }
        return car;
    }

    public Car(){
    }
}
// 用final关键字操作，需要写在另一个class中，所以舍弃了
class Tom{
    public final  Car car = new Car();
    public Tom(){

    }
}


// 单例模式: 饿汉式
class HungrySingleton {
    // 私有构造方法
    private HungrySingleton() {}

    // 类内部创建对象实例
    private final static HungrySingleton instance = new HungrySingleton();

    // 静态工厂方法
    public static HungrySingleton getInstance() {
        return instance;
    }
}
// 单例模式: 懒汉式
class LazySingleton {

    // 私有构造方法
    private LazySingleton() {}

    // 类内部声明对象实例
    private static LazySingleton instance = null;

    // 静态工厂方法
    public static LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}

// 单例模式: 懒汉线程安全问题
//创建方法上加锁：缺点是影响性能
class LazySecuritySingleton {

    // 私有构造方法
    private LazySecuritySingleton() {}

    // 类内部声明对象实例
    private static LazySecuritySingleton instance = null;

    // 如果方法中有多个操作，比较影响性能
    public static synchronized LazySecuritySingleton getInstance() {
        //双重检查锁
        if (instance == null) {
          instance = new LazySecuritySingleton();
        }
        return instance;
    }
}
// 单例模式: 懒汉线程安全问题
class LazySecuritySingleton2 {

    // 私有构造方法
    private LazySecuritySingleton2() {}

    // 类内部声明对象实例
    private static LazySecuritySingleton2 instance = null;

    public static LazySecuritySingleton2 getInstance() {
        //双重检查锁
        if (instance == null) {
            synchronized (LazySecuritySingleton2.class) {  // 同步块
                if (instance == null) {  // 第二次检查
                    instance = new LazySecuritySingleton2();
                }
            }
        }
        return instance;
    }
}